/*
    Code : Dzlua
    Email: 505544956@qq.com
    Time : 2017/05/26
*/
#pragma once

#include "../export.h"

#include <string>
#include <memory>

namespace dzlua {

class DZLUA_EXPORT DataBase {
public:
    enum eDataBaseType {
        DATABASE_SQLITE,
    };
    static std::unique_ptr<DataBase> NewDataBase(eDataBaseType type = DATABASE_SQLITE);
public:
    struct DataBlob {
        void* data;
        int len;
    };

    typedef int (*QueryCallback) (void *para, int n_column, char **column_value, char **column_name);

        class Command {
    public:
        virtual bool SetCommand(const std::string& sql) = 0;
        virtual bool SetCommand(const std::wstring& sql) = 0;
        virtual bool BindParam(int idx, const std::string& value) = 0;
        virtual bool BindParam(int idx, const std::wstring& value) = 0;
        virtual bool BindParam(int idx, const int value) = 0;
        virtual bool BindParam(int idx, const long value) = 0;
        virtual bool BindParam(int idx, const double value) = 0;
        virtual bool BindParam(int idx, const DataBlob* blob) = 0;
        virtual bool Excute() = 0;
        virtual void Clear() = 0;
    };

    class DataReader {
    public:
        virtual bool Read() = 0;
        virtual void Close() = 0;
        virtual int Count() = 0;
        virtual std::string NameA(int col) = 0;
        virtual std::wstring NameW(int col) = 0;
#if defined(UNICODE) || defined(_UNICODE)
		virtual std::wstring Name(int col) = 0;
		virtual std::wstring GetString(int col) = 0;
#else
		virtual std::string Name(int col) = 0;
		virtual std::string GetString(int col) = 0;
#endif
        virtual int Type(int col) = 0;
        virtual std::string GetAString(int col) = 0;
        virtual std::wstring GetWString(int col) = 0;
        virtual int GetInt(int col) = 0;
        virtual long GetInt64(int col) = 0;
        virtual double GetFloat(int col) = 0;
        virtual DataBlob GetBlob(int col) = 0;
    };

public:
    virtual std::unique_ptr<Command> NewCommand() = 0;
    virtual bool Open(const std::string& file) = 0;
    virtual bool Open(const std::wstring& file) = 0;
    virtual void Close() = 0;
    virtual bool ExcuteNonQuery(const std::string& sql) = 0;
    virtual bool ExcuteNonQuery(const std::wstring& sql) = 0;
    virtual bool ExcuteNonQuery(Command* pcmd) = 0;
    virtual std::unique_ptr<DataReader> ExcuteQuery(const std::string& sql) = 0;
    virtual std::unique_ptr<DataReader> ExcuteQuery(const std::wstring& sql) = 0;
    virtual bool ExcuteQuery(const std::string& sql, QueryCallback callback) = 0;
    virtual bool ExcuteQuery(const std::wstring& sql, QueryCallback callback) = 0;
    virtual bool BeginTransaction() = 0;
    virtual bool CommitTransaction() = 0;
    virtual bool RollbackTransaction() = 0;
    virtual std::string GetLastErrMsgA() = 0;
    virtual std::wstring GetLastErrMsgW() = 0;
#if defined(UNICODE) || defined(_UNICODE)
	virtual std::wstring GetLastErrMsg() = 0;
#else
	virtual std::string GetLastErrMsg() = 0;
#endif
};

} //end namespace dzlua
